package wci.frontend.pascal.parsers;

import static wci.frontend.pascal.PascalErrorCode.MISSING_BEGIN;
import static wci.frontend.pascal.PascalErrorCode.MISSING_END;
import static wci.frontend.pascal.PascalTokenType.BEGIN;
import static wci.frontend.pascal.PascalTokenType.END;
import static wci.intermediate.icodeimpl.ICodeNodeTypeImpl.COMPOUND;
import wci.frontend.Token;
import wci.frontend.TokenType;
import wci.frontend.pascal.PascalParserTD;
import wci.intermediate.ICodeFactory;
import wci.intermediate.ICodeNode;
import wci.intermediate.SymTabEntry;

/**
 * <h1>BlockParser</h1>
 * <p>解析Pascal中的块，块一般是多条语句的结构体</p>
 * <p>Copyright (c) 2009 by Ronald Mak</p>
 * <p>For instructional purposes only.  No warranties.</p>
 */
public class BlockParser extends PascalParserTD
{
    public BlockParser(PascalParserTD parent)
    {
        super(parent);
    }

    /**
     * 解析块，看语法图，块首先是申明，然后是复合语句
     * @param token 开头的token
     * @param routineId 程式标识符的符号表项
     * @return the 分析树的根节点
     * @throws Exception 
     */
    public ICodeNode parse(Token token, SymTabEntry routineId)
        throws Exception
    {
        DeclarationsParser declarationsParser = new DeclarationsParser(this);
        StatementParser statementParser = new StatementParser(this);

        declarationsParser.parse(token,routineId);

        token = synchronize(StatementParser.STMT_START_SET);
        TokenType tokenType = token.getType();
        ICodeNode rootNode = null;

        // 判断是否是一个复合语句，否则报错并继续解析
        if (tokenType == BEGIN) {
            rootNode = statementParser.parse(token);
        }
        else {
            errorHandler.flag(token, MISSING_BEGIN, this);
            if (StatementParser.STMT_START_SET.contains(tokenType)) {
                rootNode = ICodeFactory.createICodeNode(COMPOUND);
                statementParser.parseList(token, rootNode, END, MISSING_END);
            }
        }

        return rootNode;
    }
}
